/**
 * 
 */
package neptune.web.client.view;

import neptune.web.client.view.input.DefaultInputValidator;
import neptune.web.client.view.input.InputValidator;

import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.PushButton;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * This class realizes a log-in panel.<br/>
 * The class uses an InputValidator to validete the username and password
 * inputs.
 * 
 * @author Roberto Bifulco [info@robertobifulco.it, robertobifulco.it]
 * 
 */
public class LogInView extends View implements ClickListener, HasConsole {

	// TODO usare imageBundle in questa classe
	public static final String DEFAULT_TOKEN = "LogIn";
	private TextBox username;
	private PasswordTextBox password;
	private VerticalPanel reportConsolePanel;
	private ScrollPanel reportConsolePanelWrap;

	private InputValidator inputValidator = new DefaultInputValidator();
	private LogInViewListener listener;

	private String welcomeMessage = "Welcome to the Neptune Network Emulator!";
	private String htmlPresentation = "Neptune-network-emulator is an open source project. " +
			"Project infos can be found on " +
			"<a href=\"http://code.google.com/p/neptune-network-emulator/\">the project page</a>.";

	/**
	 * Builds the interface<br/>
	 * <br/>
	 * 
	 * Styles are:<br/>
	 * .LogInPanel<br/>
	 * others...
	 */
	public LogInView() {
		// Setting view params
		try {
			this.setName(DEFAULT_TOKEN);
		} catch (DuplicatedTokenException e) {
			ConsoleManager.addConsoleDebugMessage(e.getMessage(), true);
		}
		username = new TextBox();
		username.setText("username");
		password = new PasswordTextBox();
		password.setText("pass");

		// Layout building
		FlowPanel mainPanel = new FlowPanel();

		Label windowTitle = new Label("Log In Window");

		// Defining dataPanel to cotain log in form and report console
		HorizontalPanel dataPanel = new HorizontalPanel();
		// userDataPanel contains login form
		Panel userDataPanel = new FlowPanel();

		Panel usernamePanel = new HorizontalPanel();
		SimplePanel usernameWrap = new SimplePanel(); // Wrap Panel to add the
		// background
		usernameWrap.add(username);
		usernamePanel.add(usernameWrap);

		Panel passwordPanel = new HorizontalPanel();
		SimplePanel passwordWrap = new SimplePanel(); // Wrap Panel to add the
		// background
		passwordWrap.add(password);
		passwordPanel.add(passwordWrap);
		// TODO usare image bundle
		PushButton loginButton = new PushButton(new Image(
				"img/login-button.png"),
				new Image("img/login-button_hover.png"));
		loginButton.addClickListener(this);

		userDataPanel.add(usernamePanel);
		userDataPanel.add(passwordPanel);
		userDataPanel.add(loginButton);
		// end of userDataPanel definition

		dataPanel.add(userDataPanel);

		// Report Console
		reportConsolePanel = new VerticalPanel();
		reportConsolePanelWrap = new ScrollPanel(reportConsolePanel);

		addConsoleMessage(welcomeMessage, false);
		
		mainPanel.add(dataPanel);
		mainPanel.add(reportConsolePanelWrap);
		
		HTML htmlPresentationWidget = new HTML(htmlPresentation);
		htmlPresentationWidget.addStyleName("LogInPanel-presentation");
		mainPanel.add(htmlPresentationWidget);

		initWidget(mainPanel);

		// Style definitions
		username.setStyleName("LogInPanel-username");
		password.setStyleName("LogInPanel-password");
		windowTitle.setStyleName("LogInPanel-title");
		userDataPanel.setStyleName("LogInPanel-UserData");
		usernameWrap.setStyleName("LogInPanel-usernameWrap");
		passwordWrap.setStyleName("LogInPanel-passwordWrap");
		loginButton.setStyleName("LogInPanel-loginButton");
		reportConsolePanelWrap.setStyleName("LogInPanel-reportConsolePanel");

		this.setStyleName("LogInPanel");
	}

	/**
	 * Adds a message to the interface console.
	 * 
	 * @param message
	 *            the message string
	 * @param isError
	 *            true if the message must have the error format
	 */
	public void addConsoleMessage(String message, boolean isError) {

		if (reportConsolePanel.getWidgetCount() > 100)
			reportConsolePanel.getWidget(0).removeFromParent();

		Label messageLabel = new Label(message);
		if (!isError) {
			messageLabel.setStyleName("LogInPanel-consoleText-norm");
		} else
			messageLabel.setStyleName("LogInPanel-consoleText-err");

		reportConsolePanel.add(messageLabel);
		reportConsolePanelWrap.setScrollPosition(reportConsolePanel
				.getOffsetHeight());
	}

	/**
	 * Returns the first message shown in the console
	 * 
	 * @return String
	 */
	public String getWelcomeMessage() {
		return welcomeMessage;
	}

	/**
	 * Sets the first message to show into console
	 * 
	 * @param welcomeMessage
	 */
	public void setWelcomeMessage(String welcomeMessage) {
		this.welcomeMessage = welcomeMessage;
	}

	/**
	 * This class is a ClickLister for its log-in button
	 * 
	 */
	public void onClick(Widget sender) {
		if (inputValidator.isValid(username.getText())
				&& inputValidator.isValid(password.getText())) {
			if (listener != null) {
				ConsoleManager.addConsoleMessage("Logging in as "
						+ username.getText() + "...", false);
				listener.logInStarted(username.getText(), password.getText(),
						this);
			}
		} else {
			ConsoleManager.addConsoleMessage("Invalid username or password!",
					true);
		}
		this.username.setText("");
		this.password.setText("");
	}

	/**
	 * Returns the InputValidator used to validate the username and password
	 * inputs
	 * 
	 * @return InputValidator
	 */
	public InputValidator getInputValidator() {
		return inputValidator;
	}

	/**
	 * Sets the InputValidator used to validate the username and password inputs
	 * 
	 * @param inputValidator
	 */
	public void setInputValidator(InputValidator inputValidator) {
		this.inputValidator = inputValidator;
	}

	/**
	 * Return the actual LogInPanelListener
	 * 
	 * @return
	 */
	public LogInViewListener getListener() {
		return listener;
	}

	/**
	 * Sets the LogInPanelListner to listen to log-in request events.
	 * 
	 * @param listener
	 */
	public void setListener(LogInViewListener listener) {
		this.listener = listener;
	}
}
